package com.alibaba.citrus.ots.sales.plan.repository;

import com.alibaba.citrus.ots.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.ots.sales.plan.repository.request.OrganizationListQueryRequest;
import com.alibaba.citrus.ots.sales.plan.repository.response.EmployeeRoleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.BaselineGetEmployeeByIdsRequest;
import com.epoch.app.bcots.model.dto.BaselineGetEmployeeRolesByIdRequest;
import com.epoch.app.bcots.model.dto.BaselineGetEmployeeRolesByIdResponse;
import com.epoch.app.bcots.model.dto.BaselineGetEmployeesByRelationOrgIdRequest;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByTypeRequest;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.domain.customersalescope.dto.CustomerSaleScopeLoadListRequest;
import com.epoch.app.otsplatformenhance.domain.customersalescope.model.CustomerSaleScope;
import com.epoch.app.otsplatformenhance.domain.customersalescope.service.CustomerSaleScopeService;
import com.epoch.app.otsplatformenhance.model.dto.GetDownOrganizationListRequest;
import com.epoch.app.otsplatformenhance.model.dto.GetTopOrganizationListRequest;
import com.epoch.app.otsplatformenhance.model.dto.TopOrganizationListResponse;
import com.epoch.app.otsplatformenhance.sdo.EmployeeSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.otsplatformenhance.service.OtsPlatformEnhanceService;
import com.google.gson.internal.LinkedTreeMap;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class PlatformEnhanceRepositoryImpl implements PlatformEnhanceRepository {

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private CustomerSaleScopeService customerSaleScopeService;

    @Autowired
    private OtsPlatformEnhanceService otsPlatformEnhanceService;

    @Override
    @RepositoryInvoker(printLog = true)
    public List<String> queryCustomerByBizType(String bizType) {
        CustomerSaleScopeLoadListRequest request = new CustomerSaleScopeLoadListRequest();
        request.setOrgSaleDepartmentCode(bizType);
        Result<List<CustomerSaleScope>> response = customerSaleScopeService.loadCustomerSaleScopeList(request);
        return response.getResult().stream().map(CustomerSaleScope::getCustomerCode).distinct().collect(Collectors.toList());
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<OrganizationSDO> queryOrganizationByBizId(String bizType, String bizId, String type) {
        BaselineGetOrganizationByTypeRequest request = new BaselineGetOrganizationByTypeRequest();
        request.setBizId(bizId);
        request.setType(type);
        request.setBizType(bizType);
        Object response = baseDataService.baselineGetOrganizationByType(request);
        return buildResponse(response);
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<OrganizationSDO> queryOrganizationByIds(List<String> ids) {
        BaselineGetOrganizationByIdsRequest request = new BaselineGetOrganizationByIdsRequest();
        request.setIds(ids);
        Object response = baseDataService.baselineGetOrganizationByIds(request);
        return buildResponse(response);
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<OrganizationSDO> getTopOrganizationList(OrganizationListQueryRequest request) {
        Result<List<TopOrganizationListResponse>> result = otsPlatformEnhanceService.getTopOrganizationList(convert(request));
        if (null != result && result.isSuccess()) {
            return result.getResult().stream().map(this::convert).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 获取当前组织底下的员工
     *
     * @param organizationId
     * @param status
     * @return
     */
    @Override
    @RepositoryInvoker(printLog = true)
    public List<EmployeeSDO> getEmployeeList(String organizationId, Integer status) {
        BaselineGetEmployeesByRelationOrgIdRequest request = new BaselineGetEmployeesByRelationOrgIdRequest();
        request.setId(organizationId);
        Object object = baseDataService.baselineGetEmployeesByRelationOrgId(request);
        return buildEmployeeSDOList(object);
    }

    /**
     * 根据id获取用户所有角色
     *
     * @param employeeId
     * @param status
     * @return
     */
    @Override
    @RepositoryInvoker(printLog = true)
    public List<EmployeeRoleResponse> getEmployeeRoleListById(String employeeId, Integer status) {
        BaselineGetEmployeeRolesByIdRequest request = new BaselineGetEmployeeRolesByIdRequest();
        request.setEmployeeId(employeeId);
        BaselineGetEmployeeRolesByIdResponse response = baseDataService.baselineGetEmployeeRolesById(request);
        return buildEmployeeRoleList(response);
    }

    /**
     * 批量获取员工信息
     *
     * @param employeeIdList
     * @return
     */
    @Override
    @RepositoryInvoker(printLog = true)
    public List<EmployeeSDO> getEmployeeList(List<String> employeeIdList) {
        BaselineGetEmployeeByIdsRequest request = new BaselineGetEmployeeByIdsRequest();
        request.setEmployeeIdList(employeeIdList);
        Result<List<com.epoch.app.bcots.model.dto.EmployeeSDO>> result = baseDataService.baselineGetEmployeeByIds(request);
        if (null == result || CollectionUtils.isEmpty(result.getResult())) {
            return null;
        }
        return result.getResult().stream().map(employeeSDO -> {
            EmployeeSDO target = new EmployeeSDO();
            BeanUtils.copyProperties(employeeSDO, target);
            return target;
        }).collect(Collectors.toList());
    }

    /**
     * 向下查询某个组织的指定层级组织
     *
     * @param request
     * @return
     */
    @Override
    public List<OrganizationSDO> getDownOrganizationList(OrganizationListQueryRequest request) {
        GetDownOrganizationListRequest organizationListRequest = new GetDownOrganizationListRequest();
        organizationListRequest.setId(request.getId());
        organizationListRequest.setType(request.getType());
        Result<List<OrganizationSDO>> result = otsPlatformEnhanceService.getDownOrganizationList(organizationListRequest);
        if (null == result || CollectionUtils.isEmpty(result.getResult())) {
            return null;
        }
        return result.getResult();
    }

    private List<EmployeeRoleResponse> buildEmployeeRoleList(BaselineGetEmployeeRolesByIdResponse response) {
        if (null == response) {
            return null;
        }
        List<?> list = response.getResult();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().map(json -> JSONObject.parseObject(JSONObject.toJSONString(((LinkedTreeMap<String, Object>)json).get("roleSDO")), EmployeeRoleResponse.class)).collect(Collectors.toList());
    }

    private List<EmployeeSDO> buildEmployeeSDOList(Object object) {
        if (null == object) {
            return null;
        }
        // 转换
        LinkedTreeMap<String, Object> jsonObject = (LinkedTreeMap<String, Object>)object;
        if (MapUtils.isEmpty(jsonObject)) {
            return null;
        }
        List<?> jsonArray = (List<?>)jsonObject.get("result");
        if (null == jsonArray) {
            return null;
        }
        return jsonArray.stream().map(json -> JSONObject.parseObject(JSONObject.toJSONString(((LinkedTreeMap<String, Object>)json).get("employeeSDO")), EmployeeSDO.class)).collect(Collectors.toList());
    }

    private OrganizationSDO convert(TopOrganizationListResponse source) {
        if (null == source) {
            return null;
        }
        OrganizationSDO target = new OrganizationSDO();
        target.setId(source.getId());
        target.setName(source.getName());
        target.setCode(source.getCode());
        target.setStatus(source.getStatus());
        target.setBizId(source.getBizId());
        target.setBizType(source.getBizType());
        target.setParentId(source.getParentId());
        target.setHasChildren(source.getHasChildren());
        target.setType(source.getType());
        return target;
    }

    private GetTopOrganizationListRequest convert(OrganizationListQueryRequest source) {
        if (null == source) {
            return null;
        }
        GetTopOrganizationListRequest target = new GetTopOrganizationListRequest();
        target.setId(source.getId());
        target.setType(source.getType());
        return target;
    }

    private List<OrganizationSDO> buildResponse(Object response) {
        LinkedTreeMap<String, Object> linkedTreeMap = (LinkedTreeMap<String, Object>) response;
        List<LinkedTreeMap<String, Object>> linkedTreeMapResult = (List<LinkedTreeMap<String, Object>>) linkedTreeMap.get("result");
        return linkedTreeMapResult.stream().map(result -> {
            return JSONObject.parseObject((JSON.toJSONString(result.get("organizationSDO"))), OrganizationSDO.class);
        }).collect(Collectors.toList());
    }
}
